﻿
namespace n_Shape
{
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using n_GUIset;
using n_MyObjectList;
using n_HardModule;
using n_MyObject;
using n_GroupList;
using n_MainSystemData;

//图形和形状类
static class Shape
{
	static Pen LinePen;
	static Pen LinePen1;
	
	public static bool ExistCircuit;
	public static bool ExistLAPI;
	public static bool NoVisibleModule;
	
	//初始化
	public static void Init()
	{
		System.Drawing.Drawing2D.AdjustableArrowCap AC = new AdjustableArrowCap( 3, 4, true );
		
		if( SystemData.isBlack ) {
			LinePen = new Pen( Color.FromArgb(170, 220, 110), 1 );
		}
		else {
			LinePen = new Pen( Color.FromArgb(230, 130, 65), 1 );
		}
		LinePen.CustomStartCap = AC;
		LinePen.DashStyle = DashStyle.Dash;
		LinePen.DashPattern = new float[]{10,10};
		
		LinePen1 = new Pen( GUIset.myBackColor, 1 );
		LinePen1.DashStyle = DashStyle.Dash;
		LinePen1.DashPattern = new float[]{10,10};
		LinePen1.DashOffset = 10;
	}
	
	//================================================================
	
	//绘制事件连接线
	public static void DrawEventLine( Graphics g, GroupList mGroupList, MyObject Source, MyObject Target )
	{
		float PXA1;
		float PYA1;
		float PXB1;
		float PYB1;
		int H = (Target.SX - Source.MidX) * 8 / 10;
		if( H < 0 ) {
			H = -H;
		}
		//计算源对象的坐标点
		if( Source.GroupMes != null && !Source.GroupVisible ) {
			Group gr = mGroupList.FindGroup( Source.GroupMes );
			PXA1 = gr.GetMidX();
			PYA1 = gr.GetMidY() + Group.HeadSize;
		}
		else {
			PXA1 = Source.MidX;
			PYA1 = Source.MidY + Source.Height*3/4;
		}
		//计算目标对象的坐标点
		if( Target.GroupMes != null && !Target.GroupVisible ) {
			Group gr = mGroupList.FindGroup( Target.GroupMes );
			PXB1 = gr.GetMidX();
			PYB1 = gr.GetMidY();
		}
		else {
			PXB1 = Target.SX;
			PYB1 = Target.MidY - Target.Height;
		}
		//绘图
		PointF PA = new PointF( PXA1, PYA1 );
		PointF PA1 = new PointF( PXA1 + 0, PYA1 + H );
		PointF PB1 = new PointF( PXB1, PYB1 - H );
		PointF PB = new PointF( PXB1, PYB1 );
		g.DrawBezier( LinePen1, PB, PB1, PA1, PA );
		g.DrawBezier( LinePen, PB, PB1, PA1, PA );
	}
	
	//================================================================
	
	//返回指令圆角矩形
	public static GraphicsPath CreateRoundedRectanglePath(RectangleF rect )
	{
		int cornerRadius = 4;
		
		GraphicsPath roundedRect = new GraphicsPath();
		roundedRect.AddArc(rect.X, rect.Y, cornerRadius * 2, cornerRadius * 2, 180, 90);
		roundedRect.AddLine(rect.X + cornerRadius, rect.Y, rect.Right - cornerRadius, rect.Y);
		roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y, cornerRadius * 2, cornerRadius * 2, 270, 90);
		roundedRect.AddLine(rect.Right, rect.Y + cornerRadius, rect.Right, rect.Y + rect.Height - cornerRadius);
		roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y + rect.Height - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 0, 90);
		roundedRect.AddLine(rect.Right - cornerRadius, rect.Bottom, rect.X + cornerRadius, rect.Bottom);
		roundedRect.AddArc(rect.X, rect.Bottom - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90);
		roundedRect.AddLine(rect.X, rect.Bottom - cornerRadius, rect.X, rect.Y + cornerRadius);
		roundedRect.CloseFigure();
		return roundedRect;
	}
	
	//返回框架圆角矩形
	public static  GraphicsPath CreateRoundedRectanglePath1(RectangleF rect )
	{
		int cornerRadius = 15;
		
		GraphicsPath roundedRect = new GraphicsPath();
		roundedRect.AddArc(rect.X, rect.Y, cornerRadius * 2, cornerRadius * 2, 180, 90);
		roundedRect.AddLine(rect.X + cornerRadius, rect.Y, rect.Right - cornerRadius, rect.Y);
		roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y, cornerRadius * 2, cornerRadius * 2, 270, 90);
		roundedRect.AddLine(rect.Right, rect.Y + cornerRadius, rect.Right, rect.Y + rect.Height - cornerRadius);
		roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y + rect.Height - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 0, 90);
		roundedRect.AddLine(rect.Right - cornerRadius, rect.Bottom, rect.X + cornerRadius, rect.Bottom);
		roundedRect.AddArc(rect.X, rect.Bottom - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90);
		roundedRect.AddLine(rect.X, rect.Bottom - cornerRadius, rect.X, rect.Y + cornerRadius);
		roundedRect.CloseFigure();
		return roundedRect;
	}
	
	//获取组件列表边界
	public static void GetArea( n_ImagePanel.ImagePanel GPanel, MyObjectList myModuleList, ref float MinX, ref float MinY, ref float MaxX, ref float MaxY, ref float C_MinX, ref float C_MinY, ref float C_MaxX, ref float C_MaxY )
	{
		//bool Exist = false;
		bool isFirst = true;
		bool isFirstC = true;
		ExistCircuit = false;
		ExistLAPI = false;
		NoVisibleModule = true;
		
		foreach( n_MyObject.MyObject mo in myModuleList ) {
			
			//计算所有的组件边界
			if( !mo.isVisible() ) {
				continue;
			}
			NoVisibleModule = false;
			//Exist = true;
			if( isFirst ) {
				isFirst = false;
				MinX = mo.SX;
				MinY = mo.SY;
				MaxX = mo.SX + mo.Width;
				MaxY = mo.SY + mo.Height;
			}
			else {
				if( MinX > mo.SX ) {
					MinX = mo.SX;
				}
				if( MinY > mo.SY) {
					MinY = mo.SY;
				}
				if( MaxX < mo.SX + mo.Width ) {
					MaxX = mo.SX + mo.Width;
				}
				if( MaxY < mo.SY + mo.Height ) {
					MaxY = mo.SY + mo.Height;
				}
			}
			if( !(mo is HardModule) ) {
				continue;
			}
			HardModule hm = (HardModule)mo;
			if( hm.ImageName == n_GUIcoder.SPMoudleName.SYS_LAPI ) {
				ExistLAPI = true;
			}
			if( !hm.isCircuit ) {
				continue;
			}
			ExistCircuit = true;
			
			if( isFirstC ) {
				isFirstC = false;
				C_MinX = mo.SX;
				C_MinY = mo.SY;
				C_MaxX = mo.SX + mo.Width;
				C_MaxY = mo.SY + mo.Height;
			}
			else {
				if( C_MinX > mo.SX ) {
					C_MinX = mo.SX;
				}
				if( C_MinY > mo.SY) {
					C_MinY = mo.SY;
				}
				if( C_MaxX < mo.SX + mo.Width ) {
					C_MaxX = mo.SX + mo.Width;
				}
				if( C_MaxY < mo.SY + mo.Height ) {
					C_MaxY = mo.SY + mo.Height;
				}
			}
		}
		if( GPanel != null ) {
			foreach( n_GroupList.Group mo in GPanel.mGroupList ) {
				
				//Exist = true;
				if( isFirst ) {
					isFirst = false;
					MinX = mo.SX;
					MinY = mo.SY;
					MaxX = mo.SX + mo.Width;
					MaxY = mo.SY + mo.Height;
					continue;
				}
				if( MinX > mo.SX ) {
					MinX = mo.SX;
				}
				if( MinY > mo.SY) {
					MinY = mo.SY;
				}
				if( MaxX < mo.SX + mo.Width ) {
					MaxX = mo.SX + mo.Width;
				}
				if( MaxY < mo.SY + mo.Height ) {
					MaxY = mo.SY + mo.Height;
				}
			}
		}
		//return Exist;
	}
	
	//获取交线
	public static void GetCross( int padding, int mX, int mY, int mWidth, int mHeight, int mForceX, int mForceY, ref int cmX, ref int cmY )
	{
		mWidth += padding * 2;
		mHeight += padding * 2;
		
		float AbsFX = Math.Abs( mForceX ) + 1;
		float AbsFY = Math.Abs( mForceY ) + 1;
		float OffX = 0;
		float OffY = 0;
		if( AbsFY / AbsFX > (float)mHeight / mWidth ) {
			//注意没有考虑到除数为零
			OffX = AbsFX * (mHeight / 2) / AbsFY;
			OffY = mHeight / 2;
		}
		else {
			OffX = mWidth / 2;
			OffY = AbsFY * (mWidth / 2) / AbsFX;
		}
		if( mForceX > 0 ) {
			cmX = mX + (int)OffX;
		}
		else {
			cmX = mX - (int)OffX;
		}
		if( mForceY > 0 ) {
			cmY = mY + (int)OffY;
		}
		else {
			cmY = mY - (int)OffY;
		}
	}
	
	//================================================================
	
	//绘制折线
	public static void DrawEngineLine( Graphics g, Pen LinePen, int AX, int AY, int BX, int BY )
	{
		g.DrawLine( LinePen, AX, AY, BX, BY );
	}
	
	//绘制上下方向的经过两点的折线
	public static void DrawRectangleLine( Graphics g, Pen LinePen, int AX, int AY, int BX, int BY )
	{
		int AX1 = AX;
		int AY1 = AY + (BY - AY) / 2;
		
		int BX1 = BX;
		int BY1 = BY - (BY - AY) / 2;
		
		g.DrawLine( LinePen, AX, AY, AX1, AY1 + 1 );
		g.DrawLine( LinePen, AX1, AY1, BX1, BY1 );
		g.DrawLine( LinePen, BX1, BY1 - 1, BX, BY );
	}
	
	//绘制上下方向的经过两点的贝塞尔曲线
	public static void DrawRectangleLine1( Graphics g, Pen LinePen, int AX, int AY, int BX, int BY )
	{
		int Did = Math.Abs( BY - AY );
		g.DrawBezier( LinePen, AX, AY, AX, AY + Did, BX, BY - Did, BX, BY );
	}
	
	//绘制经过两点的折线, 考虑各个方向对称
	public static void DrawRectangleLine( Graphics g, Pen LinePen, int vAX, int vAY, int vAW, int vAH, int vBX, int vBY, int vBW, int vBH )
	{
		int AX, AY, AW, AH, BX, BY, BW, BH;
		
		int MidX1, MidY1, MidX2, MidY2;
		
		bool isSwap = false;
		
		if( vAX < vBX ) {
			AX = vAX;
			AY = vAY;
			AW = vAW;
			AH = vAH;
			BX = vBX;
			BY = vBY;
			BW = vBW;
			BH = vBH;
		}
		else {
			AX = vBX;
			AY = vBY;
			AW = vBW;
			AH = vBH;
			BX = vAX;
			BY = vAY;
			BW = vAW;
			BH = vAH;
			isSwap = true;
		}
		//如果在上边或者下边
		if( AX + AW / 2 > BX - BW / 2 ) {
			if( AY < BY ) {
				AY += AH / 2;
				BY -= BH / 2;
			}
			else {
				AY -= AH / 2;
				BY += BH / 2;
			}
			int MidY = AY + ( BY - AY ) / 2;
			
			MidX1 = AX;
			MidY1 = MidY;
			MidX2 = BX;
			MidY2 = MidY;
		}
		//如果在右边
		else if( AY + AH / 2 > BY - BH / 2 && AY - AH / 2< BY + BH / 2 ) {
			AX += AW / 2;
			BX -= BW / 2;
			int MidX = AX + ( BX - AX ) / 2;
			
			MidX1 = MidX;
			MidY1 = AY;
			MidX2 = MidX;
			MidY2 = BY;
		}
		else {
			if( AY < BY ) {
				if( Math.Abs( ( AX + AW / 2 ) - ( BX - BW / 2 ) ) > Math.Abs( ( AY + AH / 2 ) - ( BY - BH / 2 ) ) ) {
					AX += AW / 2;
					BX -= BW / 2;
					int MidX = AX + ( BX - AX ) / 2;
					
					MidX1 = MidX;
					MidY1 = AY;
					MidX2 = MidX;
					MidY2 = BY;
				}
				else {
					AY += AH / 2;
					BY -= BH / 2;
					int MidY = AY + ( BY - AY ) / 2;
					
					MidX1 = AX;
					MidY1 = MidY;
					MidX2 = BX;
					MidY2 = MidY;
				}
			}
			else {
				if( Math.Abs( ( AX + AW / 2 ) - ( BX - BW / 2 ) ) > Math.Abs( ( AY - AH / 2 ) - ( BY + BH / 2 ) ) ) {
					AX += AW / 2;
					BX -= BW / 2;
					int MidX = AX + ( BX - AX ) / 2;
					
					MidX1 = MidX;
					MidY1 = AY;
					MidX2 = MidX;
					MidY2 = BY;
				}
				else {
					AY -= AH / 2;
					BY += BH / 2;
					int MidY = AY + ( BY - AY ) / 2;
					
					MidX1 = AX;
					MidY1 = MidY;
					MidX2 = BX;
					MidY2 = MidY;
				}
			}
		}
		
		if( isSwap ) {
			//g.DrawLine( LinePen, AX, AY, MidX1, MidY1 );
			//g.DrawLine( LinePen, MidX1, MidY1, MidX2, MidY2 );
			//g.DrawLine( LinePen, MidX2, MidY2, BX, BY );
			
			g.DrawBezier( LinePen, AX, AY, MidX1, MidY1, MidX2, MidY2, BX, BY );
		}
		else {
			//g.DrawLine( LinePen, BX, BY, MidX2, MidY2 );
			//g.DrawLine( LinePen, MidX2, MidY2, MidX1, MidY1 );
			//g.DrawLine( LinePen, MidX1, MidY1, AX, AY );
			
			g.DrawBezier( LinePen, BX, BY, MidX2, MidY2, MidX1, MidY1, AX, AY );
		}
	}
}
}

